﻿using AutoMapper;
using Fonour.Application.Dtos;
using Fonour.Application.Services.Interfaces;
using Fonour.Domain;
using Fonour.Domain.IRepositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Fonour.Application.Services
{
    public abstract class ServiceBase<TDto, TEntity> : IServiceBase<TDto, TEntity>
        where TEntity : Entity
    {
        private readonly IRepository<TEntity, Guid> _repository;
        private readonly IMapper _mapper;

        public ServiceBase(IRepository<TEntity, Guid> repository, IMapper mapper)
        {
            this._repository = repository;
            this._mapper = mapper;
        }

        public void Delete(Guid id)
        {
            try
            {
                this._repository.Delete(id);
            }
            catch (Exception ex)
            {
            }
        }

        public void DeleteBatch(List<Guid> ids)
        {
            try
            {
                this._repository.Delete(p => ids.Contains(p.Id));
            }
            catch (Exception ex)
            {
            }
        }

        public async Task<IEnumerable<TDto>> GetAllListAsync(Expression<Func<TEntity, object>> order)
        {
            try
            {
                var menus = await this._repository.GetAllListAsync();
                return this._mapper.Map<IEnumerable<TDto>>(menus.AsQueryable().OrderBy(order));
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public async Task<IEnumerable<TDto>> GetAllListAsync(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, object>> order)
        {
            try
            {
                var menus = await this._repository.GetAllListAsync(where);
                return this._mapper.Map<IEnumerable<TDto>>(menus.AsQueryable().OrderBy(order));
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public async Task<TDto> GetAsync(Guid id)
        {
            var menu = await this._repository.GetAsync(id);
            return this._mapper.Map<TDto>(menu);
        }

        public async Task<PageDto<TDto>> GetPageListAsync(int startPage, int pageSize, Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, object>> order)
        {
            try
            {
                var menus = await this._repository.GetPageListAsync(startPage, pageSize, where, order);
                return this._mapper.Map<PageDto<TDto>>(menus);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public bool InsertOrUpdate(TDto dto)
        {
            try
            {
                var menu = this._repository.InsertOrUpdate(this._mapper.Map<TEntity>(dto));
                return menu != null;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}
